package cn.imokay.juc.cas;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.ToString;

import java.util.concurrent.atomic.AtomicStampedReference;

/**
 * 解决cas的ABA问题
 * 什么是ABA问题：
 *      线程1拿到值为V1，重新计算写入之前，线程2也拿到了A，
 *      并先于线程1将值改为B，然后又将B改为A，此时线程1写入时，认为A没被动过，就忽略其他线程的操作，成功更新了A的值
 *
 *      举例：公款私用，被发现前将钱如数归还，但是过程是有问题的
 */
public class ABADemo {
    public static void main(String[] args) {
        Book java = new Book(1,"javabook");
        AtomicStampedReference<Book> reference = new AtomicStampedReference<>(java, 1);
        System.out.println(reference.getReference()+"\t"+reference.getStamp());

        Book php = new Book(2, "phpbook");
        System.out.println(reference.compareAndSet(java, php, 0, 2));

        System.out.println(reference.getReference()+"\t"+reference.getStamp());

    }
}

@Data
@AllArgsConstructor
@ToString
class Book{
    private int id;
    private String name;
}
